<?php

	if(!$file = db()->get(get('force_download'))) httpE(404);
	
	OB()->set_header('Content-type', $file->mime);
	OB()->set_header('Content-Disposition', 'attachment; filename="'.$file->basename());
 	OB()->set_header('Content-Transfer-Encoding', 'binary');
	OB()->set_header('Accept-Ranges', 'bytes');
  
  	$fh = fopen($file->realpath(), 'r');
  	$fs = $file->filesize;
  
	if(isset($_SERVER['HTTP_RANGE'])){
			
		$range = array_pop(explode("=",$_SERVER['HTTP_RANGE']));
		
		if(strpos($range, ',')){
			// not sure what this potential comma is about - very hard subject to research.
			// presumably a device which requests a range is capable or requesting another if it doesn't get exactly what it wants - we always give an 
			// accurate Content-range header, so the device is responsible for reading it properly if it expected us to read the request range.
			// The number of range requesting devices (e.g. download accelerators) which are capable of logging in to the SMRDE are *severely* limited
			// in any case (even DTA in firefox for example doesn't send cookies - access simply fails) - so no test has been made of this system.
			$a = explode(',', $range);
			$r1 = array_shift(explode('-', $a[0]));
			$r2 = array_pop(explode('-', $a[1]));
		}else{
			list($r1, $r2) = explode('-', $range, 2);
		}
		
		/* "If a syntactically valid byte-range-set includes at least one byte- range-spec whose first-byte-pos is less than the current length of the entity-body, or at least one suffix-byte-range-spec with a non- zero suffix-length, then the byte-range-set is satisfiable. Otherwise, the byte-range-set is unsatisfiable. If the byte-range-set is unsatisfiable, the server SHOULD return a response with a status of 416 (Requested range not satisfiable). Otherwise, the server SHOULD return a response with a status of 206 (Partial Content) containing the satisfiable ranges of the entity-body."  */
		
		// r2 may be missing, greater than the filesize or on its own, in which case the second range parameter is filesize -1
		// Otherwise it signifies an actual end to bytes requested
		$r2 = ((($n = (int)$r2) >= $fs) || ($r1 === '') || ($r2 === '')) ? $fs-1 : $n;
		// r1 may be missing, in which case it is filesize minus r2 minus 1, or it may be a start range less than the filesize
		$r1 = ($r1 == '') ? ($fs -$n -1) : (int)$r1;
		if($r1 >= $fs){
			fclose($fh);
			httpE(416);
		}
		OB()->set_status(206);
		OB()->set_header('Content-Range', "bytes $r1-$r2/$fs");
 		$fs = $r2-$r1+1;
		fseek($fh, $r1);
	}
	
	OB()->set_header('Content-length', $fs);
	OB()->put_headers();
	OB()->clean();
 
 	$n = 0;
 	$y = 256;
 	while(!feof($fh) && !connection_aborted()){
		echo fread($fh, $y);
		if(ob_get_level()) ob_flush();
		flush();
		$n = $n + $y;
		if(($y = min($y, $fs-$n)) <= 0) break;
	}
	
	fclose($fh);
	exit;

?>